import os
import requests
from jieba import lcut
from time import sleep
from fake_useragent import UserAgent



def Spacedown(rawUrl, **kwargs):
	"""

	:param rawUrl: 哔哩哔哩个人空间地址(url)
	:param **kwargs: 下载参数:
		1.  playNumber: 播放次数
			collectNumber: 收藏次数
			shareNumber: 分享次数
			coinNumber: 投币次数
			likeNumber: 点赞次数
			playSeqnumber: 播放次数次序
			collectSeqnumber: 收藏次数次序
			shareSeqnumber: 分享次数次序
			coinSeqnumber: 投币次数次序
			likeSeqnumber: 点赞次数次序
		2.  tagHave: 标签限定有
			tagNone: 标签限定无
		3.  releaseLatest：最晚发布时间
			releaseEarliest: 最早发布时间 (Unix 时间戳)
		4.  timeMax: 最长时长
			timeMin: 最短时长(秒)
		5.  keywordHave: 关键词限定有
			keywordNone: 关键词限定无

	:return: 下载url 列表
	"""

	# 参数预处理
	if kwargs != { }:
		# 是否要访问html
		if "collectNumber" in kwargs or "shareNumber" in kwargs or "coinNumber" in kwargs or "likeNumber" in kwargs:
			html_req = True
		else:
			if "collectSeqnumber" in kwargs or "shareSeqnumber" in kwargs or "coinSeqnumber" in kwargs or "likeSeqnumber" in kwargs:
				html_req = True
			else:
				html_req = False

		# 是否要访问tag api
		if "tagNone" in kwargs or "tagHave" in kwargs:
			tag_req = True
		else:
			tag_req = False

		# 是否要进行分词
		if "keywordNone" in kwargs or "keywordHave" in kwargs:
			word_lcut = True
		else:
			word_lcut = False

	html_req = True
	tag_req = True
	word_lcut = True

	# url 预处理
	space_url = str(rawUrl.replace("https://", ""))
	# 判断是否为哔哩哔哩个人空间url
	if space_url.startswith("space.bilibili.com/"):
		space_url = space_url.replace("space.bilibili.com/", "")
	else:
		return False

	# 获取哔哩哔哩个人空间代码
	space_code = space_url.split("/")[0]
	# 请求url初步编码
	space_param = { "mid": space_code, "ps": 30, "tid": 0,
	                "pn" : None, "keyword": None, "order": "pubdate", "jsonp": "jsonp" }
	pages_info = []
	videos_count = 0
	for i in range(1, 21):
		# 循环请求url
		# 哔哩哔哩每一页显示30个视频，请求20次就是600个，应该不会到这个数吧……

		space_param["pn"] = i
		page_info = requests.get("https://api.bilibili.com/x/space/arc/search"
		                         , params = space_param).json()

		# 判断是否是最后一页
		if page_info["data"]["list"]["tlist"] is None:
			break

		# 添加视频信息
		for j in page_info["data"]["list"]["vlist"]:
			sleep(0.1)
			# 对处理较复杂的数据进行预处理
			length_tmp = 60 * int(j["length"].split(":")[0]) + int(j["length"].split(":")[1])
			if word_lcut:
				description_tmp = lcut(j["description"].replace(" ", ""))
				title_tmp = lcut(j["title"].replace(" ", ""))
			else:
				description_tmp = None
				title_tmp = None

			# tag数据添加
			if tag_req:
				tag_raw = requests.get(url = "https://api.bilibili.com/x/web-interface/view/detail/tag?aid=" +
				                             str(j["aid"])).json()
				tag_list = [o["tag_name"] for o in tag_raw["data"]]
			else:
				tag_list = None

			# 收藏，转发，投币数据添加：
			if html_req:
				head = { "user-agent": UserAgent().random }
				data_tmp = requests.get("http://api.bilibili.com/x/web-interface/view?bvid=" + j["bvid"],
				                        headers = head).json()["data"]["stat"]
				collect_tmp = data_tmp["favorite"]
				share_tmp = data_tmp["share"]
				coin_tmp = data_tmp["coin"]
				like_tmp = data_tmp["like"]
			else:
				collect_tmp = None
				share_tmp = None
				coin_tmp = None
				like_tmp = None

			# 数据最后合成添加
			pages_info.append({ "number"     : videos_count,
			                    "like"       : like_tmp,
			                    "description": description_tmp,
			                    "title"      : title_tmp,
			                    "created"    : j["created"],
			                    "length"     : length_tmp,
			                    "aid"        : j["aid"],
			                    "bvid"       : j["bvid"],
			                    "play"       : j["play"],
			                    "tag"        : tag_list,
			                    "collect"    : collect_tmp,
			                    "share"      : share_tmp,
			                    "coin"       : coin_tmp })

			videos_count = videos_count + 1

		# 添加视频数量信息
		i = i + 1

	word_select = []
	if word_lcut:
		# 添加关键词排除和查找列表
		try:
			key_except_list = kwargs["keywordsNone"]
		except KeyError:
			key_except_list = set()
		try:
			key_list = kwargs["keywordshave"]
		except KeyError:
			key_list = set()
		
		for i in pages_info:
			# 提取关键词set
			key_set = set(i["description"] + i["title"])
			if not (key_set & key_except_list) and (key_set & key_list):
				word_select.append(i)
	else:
		word_select = pages_info

	tag_select = []
	if tag_req:
		# 添加标签排除和查找列表
		try:
			tag_except_list = kwargs["tagNone"]
		except KeyError:
			tag_except_list = set()
		try:
			tag_list = kwargs["taghave"]
		except KeyError:
			tag_list = set()

		for i in word_select:
			# 提取标签set
			tag_set = set(i["tag"])
			if not (tag_set & tag_except_list) and (tag_set & tag_list):
				tag_select.append(i)
	else:
		tag_select = word_select

	time_select = []
	if "releaseLatest" in kwargs or "releaseEarliest" in kwargs or "timeMax" in kwargs or "timeMin" in kwargs:
		# 时间参数的判断
		try:
			time_min = kwargs["timeMin"]
		except KeyError:
			time_min = 0
		try:
			time_max = kwargs["timeMax"]
		except KeyError:
			time_max = 10000000000  # 应该不会有超过这个时间的视频~~
		try:
			release_earliest = kwargs["releaseEarliest"]
		except KeyError:
			release_earliest = 0
		try:
			release_latest = kwargs["releaseLatest"]
		except KeyError:
			release_latest = 1000000000000000000

		for i in tag_select:
			# 提取发布时间和内容时长
			length = i["length"]
			release = i["created"]
			if (time_min <= length <= time_max) and (release_earliest <= release <= release_latest):
				time_select.append(i)
	else:
		time_select = tag_select

	# 视频热度信息筛选：
	final_select = []
	if "playNumber" in kwargs or "playSeqnumber" in kwargs or html_req:
		# 对视频热度信息的添加
		# 由于参数量过大，所以使用exec参数重复执行
		code_text = """if "*Number" in kwargs:
			*_number = kwargs["*Number"]
		else:
			*_number = 0
		"""
		loop_list = ["play","collect","share","coin","like"]
		for i in loop_list:
			exec(code_text.replace("*",i))
		# 判断是否有排序需求，用5是为了计算方便
		seq_true = 5
		# 同上
		code_text = """if "*Seqnumber" in kwargs:
			*_seq_number = kwargs["*Seqnumber"]
		else:
			*_seq_number = 0
			seq_true -= 1"""
		for i in loop_list:
			exec(code_text.replace("*",i))

		code_text_1 = """* = i["*"]"""
		eval_text = "and".join([" ({}_number <= {}) ".format(i,i) for i in loop_list])
		for i in time_select:
			# 同上
			for i in ["play", "collect", "share", "coin", "like"]:
				exec(code_text_1.replace("*", i))

			if not seq_true:
				if eval(eval_text):
					final_select.append(i)












	print(pages_info, page_info)
